<?php

namespace maotool\script;

use maotool\core\lang\Usage;
use maotool\object\ReflectionUtil;
use maotool\object\StrUtil;
use maotool\util\ArrayUtil;
use maotool\util\IdUtil;

class PhpScriptUtil
{

    /**
     * php脚本解析器
     * @param $script
     * @param $params
     * @param $usages Usage[]
     * @param $namespace
     * @return mixed
     */
    public static function parse($script, $params = [], $usages = [], $namespace = "maotool\script")
    {
        $className = "C" . IdUtil::simpleUUID();
        $mainName = "m" . IdUtil::simpleUUID();
        $scripts = [];
        $scripts[] = "namespace " . StrUtil::replace("/", "\\", $namespace) . ";";
        if (count($usages)) {
            $scripts[] = "";
            foreach ($usages as $usage) {
                $scripts[] = $usage->getRaw();
            }
        }
        $scripts[] = "";
        $scripts[] = "class " . $className;
        $scripts[] = "{";
        $scripts[] = "    public static function " . $mainName . "()";
        $scripts[] = "    {";
        $scripts[] = "//      定义局部变量";
        foreach ($params as $key => $value) {
            $scripts[] = "        \$" . $key . " = unserialize(urldecode(\"" . urlencode(serialize($value)) . "\"));";
        }
        $scripts[] = "//      运行脚本";
        $scripts[] = "        " . $script;
        $scripts[] = "    }";
        $scripts[] = "}\n";
        $scripts[] = "return " . $className . "::" . $mainName . "();\n\n";
        return eval(ArrayUtil::join($scripts, "\n"));
    }

    /**
     * php表达式解析
     * @param $expression
     * @param $params
     * @param $uses
     * @param $namespace
     * @return mixed
     */
    public static function expression($expression, $params = [], $uses = [], $namespace = "maotool\script")
    {
        return self::parse("return " . $expression . ";", $params, $uses, $namespace);
    }

    /**
     * php参数解析
     * @param $params
     * @return mixed
     */
    public static function methodParams($params){
        return ReflectionUtil::getMethodParams(eval("return function(".$params."){};"));
    }

    /**
     * php参数解析
     * @param $params
     * @param $name
     * @return mixed
     */
    public static function methodParam($params, $name){
        return ReflectionUtil::getMethodParam(eval("return function(".$params."){};"), $name);
    }

}